/**
* 版权声明：厦门睿商网络科技有限公司 版权所有 违者必究
* 日    期：2020-08-02
*/
package com.rzico.order.service;

import com.rzico.base.BaseMapper;
import com.rzico.base.impl.BaseServiceImpl;
import com.rzico.basics.entity.Bom;
import com.rzico.basics.entity.Enterprise;
import com.rzico.basics.entity.Product;
import com.rzico.basics.mapper.BomMapper;
import com.rzico.basics.service.BomItemService;
import com.rzico.basics.service.BomService;
import com.rzico.basics.service.EnterpriseService;
import com.rzico.basics.service.ProductService;
import com.rzico.exception.CustomException;
import com.rzico.order.entity.*;
import com.rzico.order.enumx.WarehouseTypeEnum;
import com.rzico.util.DateUtils;
import com.rzico.util.RedisHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import com.rzico.order.mapper.OrderPlanMapper;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * <pre>
 * 套餐配送计划业务类
 * </pre>
 *
 * @author Rzico Boot
 * @version 1.0
 */
@Service
public class OrderPlanService extends BaseServiceImpl<OrderPlan, String> {

    @Autowired
    private OrderPlanMapper orderPlanMapper;

    @Autowired
    private ProductService productService;

    @Autowired
    private BomService bomService;

    @Autowired
    private BomItemService bomItemService;

    @Autowired @Lazy
    private OrderService orderService;

    @Autowired
    private EnterpriseService enterpriseService;

    @Override
    public BaseMapper<OrderPlan, String> getMapper() {
        return orderPlanMapper;
    }

    public List<OrderPlan> getItemList(Long enterpriseId,Long orderId,Long productId) {

        Map<String,Object> params = new HashMap<>();
        params.put("enterpriseId", enterpriseId);
        params.put("orderId", orderId);
        params.put("productId", productId);
        params.put("sortField", "id");
        params.put("sortType","asc");
        List<OrderPlan> orderPlanList = orderPlanMapper.selectList(params);

        return orderPlanList;

    }

    @Transactional(rollbackFor = Exception.class)
    public void addWarehouse(Warehouse order) {
        if (order.getWarehouseType().equals(WarehouseTypeEnum.WAREHOUSE_TYPE_SALE_OUT.getId())) {
            addPlan(order);
        }
        if (order.getWarehouseType().equals(WarehouseTypeEnum.WAREHOUSE_TYPE_SALE_IN.getId())) {
            decPlan(order);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void delWarehouse(Warehouse order) {
        if (order.getWarehouseType().equals(WarehouseTypeEnum.WAREHOUSE_TYPE_SALE_OUT.getId())) {
            decPlan(order);
        }
        if (order.getWarehouseType().equals(WarehouseTypeEnum.WAREHOUSE_TYPE_SALE_IN.getId())) {
            addPlan(order);
        }
    }


    @Transactional(rollbackFor = Exception.class)
    public void addPlan(Warehouse warehouse) {

        Order od = orderService.selectByPrimaryKey(warehouse.getOrderId());
        Date d = enterpriseService.calcEstimateDate(warehouse.getEnterpriseId(),warehouse.getOrderDate(),od.getWeekTime());

        for (WarehouseItem orderItem:warehouse.getItemList()) {

            if (orderItem.getSubType().equals(1)) {

                if (warehouse.getOrderId()==null) {
                    throw new CustomException("套餐不能直接开出入库单");
                }
                Product product = productService.selectByPrimaryKey(orderItem.getProductId());

                //套餐时，生成配送计划
                Bom bom = null;
                Map<String,Object> params = new HashMap<>();
                params.put("enterpriseId",product.getEnterpriseId());
                params.put("productId",orderItem.getProductId());
                List<Bom> bomList = bomService.selectList(params);
                if (bomList.size()>0) {
                    bom = bomList.get(0);
                }

                if (bom==null) {
                    throw new CustomException("请设置套餐");
                }

                if (bom.getQuantity()<=1) {
                    continue;
                }


                for (int w=0;w<orderItem.getQuantity().longValue();w++) {
                    Integer seqNo = 0;

                    for (int n=0;n<bom.getQuantity();n++) {

                        //计算预计送达时间
                        while (true) {
                            String wk = DateUtils.getDayOfWeek(d);
                            if (od.getWeekTime().indexOf(wk) >= 0) {
                                break;
                            }
                            d = DateUtils.addDate(d, Calendar.DATE,1);
                        }

                        seqNo++;
                        OrderPlan orderPlan = new OrderPlan();
                        orderPlan.setEnterpriseId(warehouse.getEnterpriseId());
                        orderPlan.setCreateDate(new Date());
                        orderPlan.setName(orderItem.getName());
                        orderPlan.setSn(orderItem.getSn());
                        orderPlan.setSpec(orderItem.getSpec());
                        orderPlan.setOrderId(warehouse.getOrderId());
                        orderPlan.setUnit(orderItem.getUnit());
                        orderPlan.setStatus(0);
                        orderPlan.setBomId(bom.getId());
                        orderPlan.setMemberId(warehouse.getMemberId());
                        orderPlan.setSeqno(seqNo);
                        orderPlan.setThumbnail(orderItem.getThumbnail());
                        orderPlan.setProductId(orderItem.getProductId());
                        orderPlan.setPlanDate(d);

                        orderPlanMapper.insertUseGeneratedKeys(orderPlan);

                        d = DateUtils.addDate(d, Calendar.DATE,1);

                    }
                }


            }
        }

    }

    @Transactional(rollbackFor = Exception.class)
    public void decPlan(Warehouse warehouse) {

        Order od = orderService.selectByPrimaryKey(warehouse.getOrderId());

        for (WarehouseItem orderItem:warehouse.getItemList()) {
            if (orderItem.getSubType().equals(1)) {
                if (warehouse.getOrderId()==null) {
                    throw new CustomException("套餐不能直接开出入库单");
                }

                //送货检查是否有用掉
                Map<String, Object> params = new HashMap<>();
                params.put("used", true);
                params.put("enterpriseId", warehouse.getEnterpriseId());
                params.put("productId", orderItem.getProductId());
                params.put("orderId", warehouse.getOrderId());

                Integer w = orderPlanMapper.selectRowCount(params);
                if (w > 0) {
                    throw new CustomException("已配送不能退");
                }

                //套餐时，生成配送计划
                Bom bom = null;
                params.clear();
                params.put("enterpriseId",orderItem.getEnterpriseId());
                params.put("productId",orderItem.getProductId());
                List<Bom> bomList = bomService.selectList(params);
                if (bomList.size()>0) {
                    bom = bomList.get(0);
                }

                if (bom==null) {
                    throw new CustomException("请设置套餐");
                }

                if (bom.getQuantity()<=1) {
                    continue;
                }

                params.clear();
                params.put("enterpriseId", warehouse.getEnterpriseId());
                params.put("orderId", warehouse.getOrderId());
                params.put("productId", orderItem.getProductId());
                params.put("sortField", "id");
                params.put("sortType","desc");
                List<OrderPlan> orderPlanList = orderPlanMapper.selectList(params);

                for (int i=0;w<orderItem.getQuantity().longValue();w++) {
                    for (int n=0;n<bom.getQuantity();n++) {
                        OrderPlan orderPlan = orderPlanList.get(0);
                        Integer e = orderPlanMapper.delete(orderPlan);
                        if (e==0) {
                            throw new CustomException("退单失败");
                        }
                        orderPlanList.remove(orderPlan);
                    }
                }

            }
        }

    }

    @Transactional(rollbackFor = Exception.class)
    public void calculate(Order order,Date beginDate,Date endDate) {

        Map<String, Object> params = new HashMap<>();

        //套餐时，生成配送计划
        params.put("enterpriseId", order.getEnterpriseId());
        params.put("orderId", order.getId());
        params.put("status",0);
        params.put("sortField", "id");
        params.put("sortType","asc");
        List<OrderPlan> orderPlanList = orderPlanMapper.selectList(params);
        if (beginDate!=null && endDate!=null) {
            beginDate = org.apache.commons.lang3.time.DateUtils.truncate(beginDate, Calendar.DATE);
            endDate = org.apache.commons.lang3.time.DateUtils.truncate(endDate, Calendar.DATE);
        }
        Date today = org.apache.commons.lang3.time.DateUtils.truncate(new Date(),Calendar.DATE);

        Date d = null;

        for (OrderPlan orderPlan:orderPlanList) {

            if (d==null) {
                d = orderPlan.getPlanDate();
                Date es = enterpriseService.calcEstimateDate(order.getEnterpriseId(),new Date(),order.getWeekTime());
                if (d.after(es)) {
                    d = es;
                }
            }
            if (d.compareTo(today)<0) {
                 d = today;
            }

            //计算预计送达时间
            while (true) {
                String wk = DateUtils.getDayOfWeek(d);
                if (order.getWeekTime().indexOf(wk) >= 0) {
                    if (beginDate!=null && endDate!=null) {
                        if (d.compareTo(beginDate)>=0 && d.compareTo(endDate)<=0 ) {
                        } else {
                            break;
                        }
                    } else {
                        break;
                    }
                }
                d = DateUtils.addDate(d, Calendar.DATE,1);
            }

            orderPlan.setPlanDate(d);
            super.updateByPrimaryKeySelective(orderPlan);
            d = DateUtils.addDate(d, Calendar.DATE,1);

        }

    }

    public boolean checkAskfor(Askfor askfor) {

        for (AskforItem askforItem:askfor.getItemList()) {
            if (askforItem.getSubType().equals(1)) {

                //送货检查是否有用掉
                Map<String, Object> params = new HashMap<>();
                params.put("used", true);
                params.put("enterpriseId", askfor.getEnterpriseId());
                params.put("productId", askforItem.getProductId());
                params.put("orderId", askfor.getOrderId());

                Integer w = orderPlanMapper.selectRowCount(params);
                if (w > 0) {
                    return false;
                }

            }
        }

        return true;
    }

}
